//
//  Memory.m
//  Memento 2.0
//
//  Created by Chris Maddocks on 10-06-27.
//  Copyright 2010 Team Memento. All rights reserved.
//
//	10-08-02: Make keys consistent between initWithDictionary: and NSCoding implementation  (C. Maddocks)
//  10-08-01: Add distance property for sorting and display  (C. Maddocks)
//  10-07-21: Bump version in header to 2.0.  (C. Maddocks)
//  10-07-19: Implement NSCoding protocol for serialization  (C. Maddocks)
//  10-07-18: Changes to support caching of image data (C. Maddocks)
//  10-07-08: Fix bug when loading data by dictionary with NSNull for image or audio data (C. Maddocks)
//  10-07-05: Memory.h and Memory.m finalized for version 1. (C. Maddocks)

#import "Memory.h"

NSString *kMemoryId		= @"memoryId";
NSString *kImageFile	= @"imageFile";
NSString *kAudioFile	= @"audioFile";
NSString *kDateTime		= @"dateTime";
NSString *kLatitude		= @"latitude";
NSString *kLongitude	= @"longitude";


@implementation Memory

@synthesize memoryId, dateTime, imageFile, audioFile, location, distance, image, saving;

// This function returns filepath for a data element, given an id and extension.
+ (NSString *)filePathForId:(int)id withExtension:(NSString *)ext {
	// Get application documents directory
	NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString *docDirectory = [arrayPaths objectAtIndex:0];
	[arrayPaths release];
	[[docDirectory stringByAppendingString:[NSString stringWithFormat:@"/%d.%@", id, ext]] retain];	
	return [docDirectory autorelease];
	
}

#pragma mark -
#pragma mark Initializers

- (id)initWithDictionary:(NSDictionary *)aDictionary {
	memoryId = [[aDictionary valueForKey:kMemoryId] intValue];
	
	// Need to retain since we are not using the synthesized property setter methods. 
	// Apple recommends not using synthesized getters/setters in initialization functions.
	if ([aDictionary valueForKey:kImageFile] != [NSNull null]) {
		imageFile = [[aDictionary valueForKey:kImageFile] retain]; 		
	} else {
		imageFile = nil;
	}

	if ([aDictionary valueForKey:kAudioFile] != [NSNull null]) {
		audioFile = [[aDictionary valueForKey:kAudioFile] retain];		
 	} else {
		audioFile = nil;
	}

	dateTime = [[aDictionary valueForKey:kDateTime] retain];
	
	location.latitude = [[aDictionary valueForKey:kLatitude] doubleValue];
	location.longitude = [[aDictionary valueForKey:kLongitude] doubleValue];
	
	return self;
}

- (id)initWithMemoryId:(int)aMemoryId {
	memoryId = aMemoryId;
	self.dateTime = [NSDate date];
	
	[super init];
	return self;
}

#pragma mark -
#pragma mark NSCoding

// NSCoding method to encode Memory object for serialization
- (void)encodeWithCoder:(NSCoder *)coder
{
	[coder encodeInt:memoryId forKey:kMemoryId];
	[coder encodeObject:dateTime forKey:kDateTime];
	[coder encodeObject:imageFile forKey:kImageFile];
	[coder encodeObject:audioFile forKey:kAudioFile];
	[coder encodeDouble:location.latitude forKey:kLatitude];
	[coder encodeDouble:location.longitude forKey:kLongitude];
	// Don't encode distance, as it is a calculated value
}

// NSCoding method to init Memory object based on deserialization
- (id)initWithCoder:(NSCoder *)coder {
	[super init];
	
	memoryId = [coder decodeIntForKey:kMemoryId];
	self.dateTime = [coder decodeObjectForKey:kDateTime];
	self.imageFile = [coder decodeObjectForKey:kImageFile];
	self.audioFile = [coder decodeObjectForKey:kAudioFile];
		
	CLLocationDegrees latitude = [coder decodeDoubleForKey:kLatitude];
	CLLocationDegrees longitude = [coder decodeDoubleForKey:kLongitude];
	
	CLLocationCoordinate2D coordinates;
	coordinates.latitude = latitude;
	coordinates.longitude = longitude;

	self.location = coordinates;
	// Don't encode distance, as it is a calculated value
	
	return self;
}


#pragma mark -

- (CLLocationDistance)updateDistanceFromLocation:(const CLLocation *)aLocation {
	CLLocation *memoryLocation = [[CLLocation alloc] 
								  initWithCoordinate:self.location 
								  altitude:0 
								  horizontalAccuracy:kCLLocationAccuracyHundredMeters
								  verticalAccuracy:kCLLocationAccuracyHundredMeters
								  timestamp:self.dateTime];
	self.distance = [memoryLocation getDistanceFrom:aLocation];
	[memoryLocation release];
	
	return self.distance;	
}


- (NSString *)generateFileNameWithExt:(NSString *)ext {
	NSString *fileNameCore	= [NSString stringWithFormat:@"%d", memoryId];
	NSString *fileName		= [[fileNameCore stringByAppendingPathExtension:ext] retain];
	return [fileName autorelease];
}

- (void)dealloc {
	[dateTime release];
	[imageFile release];
	[audioFile release];
	[super dealloc];
}

@end